package com.losdun.web.controller.app;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.WxMaPhoneNumberInfo;
import com.losdun.common.annotation.Anonymous;
import com.losdun.common.config.LosdunConfig;
import com.losdun.common.core.controller.BaseController;
import com.losdun.common.core.domain.AjaxResult;
import com.losdun.common.utils.file.FileUploadUtils;
import com.losdun.common.utils.file.MimeTypeUtils;
import com.losdun.framework.web.service.TokenService;
import com.losdun.points.service.UserPointsService;
import com.losdun.weixin.controller.req.WeixinPhoneReq;
import com.losdun.weixin.domain.WechatUser;
import com.losdun.weixin.security.WxSecurityUtils;
import com.losdun.weixin.security.service.WxUserDetailsService;
import com.losdun.weixin.security.vo.WxLoginUser;
import com.losdun.weixin.service.WechatUserService;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

/**
 * @Description
 * @Author Sword.Ye
 * @Date 2025/9/22
 **/
@RestController
@RequestMapping("/app")
@Slf4j
public class AppLoginController extends BaseController {

    @Autowired
    private WxMaService wxMaService;

    @Autowired
    private WechatUserService wechatUserService;

    @Autowired
    private UserPointsService userPointsService;

    @Autowired
    private WxUserDetailsService wxUserDetailsService;

    @Autowired
    private TokenService tokenService;

    @GetMapping(value = "/getOpenId")
    @Anonymous
    public AjaxResult getOpenId(String code){
        try {
            WxMaJscode2SessionResult data = wxMaService.getUserService().getSessionInfo(code);
            return AjaxResult.success().put("data",data.getOpenid());
        } catch (Exception e) {
            log.error("授权登录失败 errmsg={}",e.getMessage(),e);
            return AjaxResult.error(e.getMessage());
        }
    }

    @PostMapping(value = "/login")
    public AjaxResult wxLogin(String code){
        try {
            WxMaJscode2SessionResult data = wxMaService.getUserService().getSessionInfo(code);
            WechatUser wxUser = wechatUserService.getWechatUserByOpenId(data.getOpenid());
            if(wxUser==null){
                wxUser=wechatUserService.createWxUser(data.getOpenid());
                //创建积分账户
                userPointsService.createAccount(wxUser.getId());
                return AjaxResult.success(data);
            }
            if (wxUser.getPhone()==null) {
                return AjaxResult.success(data);
            }
            String token= doLogin(data.getOpenid());
            return AjaxResult.success().put("token",token);
        } catch (Exception e) {
            log.error("授权登录失败 errmsg={}",e.getMessage(),e);
            return AjaxResult.error(e.getMessage());
        }
    }


    @PostMapping(value = "/getPhoneNumber")
    public AjaxResult getPhoneNumber(@RequestBody WeixinPhoneReq wxPhoneReq) {
        WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNoInfo(wxPhoneReq.getSessionKey(), wxPhoneReq.getDecryptData(), wxPhoneReq.getIv());
        return success(phoneInfo);
    }

    @PostMapping(value = "/phoneLogin")
    public AjaxResult phoneLogin(String code,String openId) {
        try {
            WxMaPhoneNumberInfo phoneInfo = wxMaService.getUserService().getPhoneNumber(code);
            if(phoneInfo==null || phoneInfo.getPhoneNumber()==null){
                throw new RuntimeException("手机号获取失败!");
            }
            if(wechatUserService.checkPhoneExists(phoneInfo.getPhoneNumber(),openId)){
                throw new RuntimeException("已有其他用户绑定了该手机号码!");
            }
            wechatUserService.bindPhone(openId,phoneInfo.getPhoneNumber());

            String token = doLogin(openId);
            return AjaxResult.success().put("token",token);
        } catch (WxErrorException e) {
            log.error("手机号获取失败 errmsg={}",e.getMessage(),e);
            return AjaxResult.error("手机号码获取失败!");
        } catch (Exception e) {
            log.error("登录失败,errmsg={}",e.getMessage(),e);
            return AjaxResult.error(e.getMessage());
        }

    }

    @GetMapping(value = "/getLoginUser")
    public AjaxResult getWxLoginUser(){
        WechatUser wechatUser = WxSecurityUtils.getWechatUser();
        return AjaxResult.success().put("user",wechatUser);
    }

    @PostMapping("/user/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
    {
        if (!file.isEmpty())
        {
            WechatUser wxUser = wechatUserService.getById(WxSecurityUtils.getUserId());
            String avatar = FileUploadUtils.upload(LosdunConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION);
            wxUser.setAvatar(avatar);
            if(wechatUserService.updateById(wxUser)){
                WxLoginUser wxLoginUser = WxSecurityUtils.getLoginUser();
                wxLoginUser.getWechatUser().setAvatar(avatar);
                tokenService.refreshWxUserToken(wxLoginUser);
                return success().put("imgUrl",avatar);
            }
        }
        return error("上传图片异常，请联系管理员");
    }



    @GetMapping(value = "/user/points")
    public AjaxResult getUserPoints()
    {
        return AjaxResult.success(userPointsService.getById(WxSecurityUtils.getUserId()));
    }

    private String doLogin(String openId) {
        WxLoginUser wxLoginUser = wxUserDetailsService.loadUserByUsername(openId);
        UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(wxLoginUser, null, wxLoginUser.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(authentication);
        return tokenService.createWxUserToken(wxLoginUser);
    }


}
